package webservice;

import contents.entities.Student;
import contents.entities.Teacher;
import contents.entities.Class;
import contents.entities.DateSubstitutions;
import contents.entities.Subject;
import contents.entities.SubstitutionItem;
import contents.entities.Timetable;
import database.Database;
import database.DatabaseEntities;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;

@WebService(serviceName = "GradebookService")
public class GradebookService {
    
    @WebMethod(operationName = "getClasses")
    public List<Class> getClasses() throws GradebookServiceException {
        Database.ensureConnectionIsOpen();
        
        List<Class> classesList = new ArrayList<Class>();

        try {
            Map<Integer, Class> classesMap = Database.selectClasses();
            for (Class schoolClass : classesMap.values()) {
                classesList.add(schoolClass);
            }
        } catch (SQLException exception) {
            throw new GradebookServiceException(exception.getMessage());
        }
        
        return classesList;
    }

    @WebMethod(operationName = "getStudentsOfClass")
    public List<Student> getStudentsOfClass(@WebParam(name = "classId") int classId) throws GradebookServiceException {
        Database.ensureConnectionIsOpen();
        
        List<Student> studentsList = new ArrayList<Student>();
        
        try {
            Map<Integer, Student> studentsMap = Database.selectStudentsOfClass(classId);
            for (Student student : studentsMap.values()) {
                studentsList.add(student);
            }
        } catch (SQLException exception) {
            throw new GradebookServiceException(exception.getMessage());
        }
        
        return studentsList;
    }
    
    @WebMethod(operationName = "getTimetablesOfClass")
    public List<Timetable> getTimetablesOfClass(@WebParam(name = "classId") int classId) throws GradebookServiceException {
        Database.ensureConnectionIsOpen();
        
        List<Timetable> timetablesList;
        
        try {
            timetablesList = Database.selectTimetablesOfClass(classId);
        } catch (SQLException exception) {
            throw new GradebookServiceException(exception.getMessage());
        }

        return timetablesList;
    }

    @WebMethod(operationName = "getTeachers")
    public List<Teacher> getTeachers() throws GradebookServiceException {
        Database.ensureConnectionIsOpen();
        
        List<Teacher> teachersList = new ArrayList<Teacher>();
        
        try {
            Map<Integer, Teacher> teachersMap = Database.selectTeachers();
            for (Teacher teacher : teachersMap.values()) {
                teachersList.add(teacher);
            }
        } catch (SQLException exception) {
            throw new GradebookServiceException(exception.getMessage());
        }
        
        return teachersList;
    }

    @WebMethod(operationName = "getSubstitutions")
    public List<DateSubstitutions> getSubstitutions() throws GradebookServiceException {
        Database.ensureConnectionIsOpen();
        
        List<DateSubstitutions> dateSubstitutionsList = new ArrayList<DateSubstitutions>();
        
        Map<Integer, DateSubstitutions> dateSubstitutionsMap = new HashMap<Integer, DateSubstitutions>();
        
        // get next monday date
        java.util.Date mondayDate = common.CommonMethods.getMondayDate();

        Date currentDate;
        
        try {
            for (int i = 0; i < 5; i++) {
                currentDate = new Date(mondayDate.getTime());
                currentDate.setDate(currentDate.getDate() + i);

                // get substitutions of the day
                List<DatabaseEntities.Substitution> substitutions = Database.selectSubstitutionsOfDate(currentDate);
            
                List<SubstitutionItem> substitutionItems = new ArrayList<SubstitutionItem>();
            
                for (int j = 0; j < substitutions.size(); j++) {
                    DatabaseEntities.Substitution substitution = substitutions.get(j);
                    
                    String className = Database.selectClassName(substitution.classId);
                    Integer lesson = Integer.valueOf(substitution.unit);
                    Subject subject = Database.getSubject(substitution.subjectId);
                    Teacher missingTeacher = Database.getTeacher(substitution.missingTeacherId);
                
                    Teacher substitutingTeacher;
                    if (substitution.substitutingTeacherId == null) {
                        substitutingTeacher = null;
                    } else {
                        substitutingTeacher = Database.getTeacher(substitution.substitutingTeacherId.intValue());
                    }
            
                    substitutionItems.add(new SubstitutionItem(className, lesson, subject, missingTeacher, substitutingTeacher));
                }
                Collections.sort(substitutionItems, new SubstitutionItem.ByClassNameAndTimeComparator());
            
                dateSubstitutionsMap.put(i, new DateSubstitutions(currentDate, substitutionItems));
            }
        
            for (DateSubstitutions dateSubstitutions : dateSubstitutionsMap.values()) {
                dateSubstitutionsList.add(dateSubstitutions);
            }
            
        } catch (SQLException exception) {
            throw new GradebookServiceException(exception.getMessage());
        }
        
        return dateSubstitutionsList;
    }
}